package com.zhongyu.order.consumer.listener;

import com.rabbitmq.client.Channel;
import com.zhongyu.comm.pojo.Task;
import com.zhongyu.comm.util.Constants;
import com.zhongyu.comm.util.JacksonUtil;
import com.zhongyu.comm.vo.CreateOrderMessage;
import com.zhongyu.order.consumer.client.OrderClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;

@Slf4j
@Component
@RabbitListener(queues = Constants.RabbitQueueName.ORDER_ADD_QUEUE)
public class OrderAddListener {

    @Resource
    private OrderClient orderClient;

    @RabbitHandler
    public void receiveTask(@Payload Task task, Channel channel, @Headers Map<String,Object> headers) throws IOException {
        System.out.println("**********************");
       log.debug("task",task);
       log.debug("requestBody",task.getRequestBody());
        channel.queueDeclare(Constants.RabbitQueueName.ORDER_ADD_QUEUE,true,false,false,null);
        //从消息中获取转账信息
        String requestBody = task.getRequestBody();
        CreateOrderMessage createOrderMessage = (CreateOrderMessage) JacksonUtil.json2Obj(requestBody,CreateOrderMessage.class);
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);

        //幂等处理，放在重复操作
        Task orderTask = orderClient.findTaskById(task.getId());
        //如果任务不存在，处理任务
        if (orderTask==null) {
            task.setTaskType("订单消费任务");
            task.setTryCount(0);
            task.setVersion(1);
            task.setStatus(0);
            task.setCreateTime(LocalDateTime.now());
            task.setErrormsg(null);
            task.setUpdateTime(null);
            orderClient.addTask(task);
            ackOrder(task, channel, deliveryTag);
        }else {
            //如果已经存在，失败次数小于三且未完成，则再次处理
            if (task.getTryCount()<3&&task.getStatus()==0){
                orderClient.updateTryCountByTaskId(task.getId(),LocalDateTime.now());
                ackOrder(task, channel, deliveryTag);
            }else {
                //任务已经完成了，不做重复处理，拒绝消息,并从队列中删除
                channel.basicReject(deliveryTag,false);
            }
        }

    }

    /**
     * 对接受的task进行应答
     * @param task
     * @param channel
     * @param deliveryTag
     * @throws IOException
     */
    private void ackOrder(@Payload Task task, Channel channel, Long deliveryTag) throws IOException {
        try {
            orderClient.processOrder(task);
            //应答成功
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            e.printStackTrace();
            //消息重回队列
            channel.basicRecover(true);
        }
    }

}
